package org.nulldevice.tankshot.entities;

import java.awt.Polygon;

import org.nulldevice.tankshot.GameContainer;

public class Bullet extends Item {

	public final static int size = 12;
	protected int speed;
	protected double realPosX, realPosY;

	protected boolean deadlyForOwner = true;

	protected Tank owner; // who has shot this bullet

	public static final int BULLETSIZE = 12;
	protected static final int bulletOffsetX = BULLETSIZE / 2;
	protected static final int bulletOffsetY = BULLETSIZE / 2;

	public Bullet(Tank owner, int posX, int posY, double angle, int speed,
			int size) {
		super(posX, posY, size, size, "", "bullet.png", bulletOffsetX,
				bulletOffsetY);
		this.owner = owner;
		this.realPosX = posX;
		this.realPosY = posY;
		this.angle = (angle + 360) % 360; // normalize angle
		this.speed = speed;
		final int[] borderX = { 0, 0, 0, 0, 0, 0, 0, 0 };
		final int[] borderY = { 0, 0, 0, 0, 0, 0, 0, 0 };
		border = new Polygon(borderX, borderY, borderX.length);
		recalcBorder = true;
		hitpoints = 2;
		deadlyForOwner = false;
	}

	public boolean isDeadlyForOwner() {
		return deadlyForOwner;
	}

	public boolean move(double delta) {
		if (deadlyForOwner == false) {
			if (!GameContainer.getInstance().isCollisions(this, owner)) {
				deadlyForOwner = true;
			}
		}

		this.realPosX = realPosX + Math.cos(Math.toRadians(angle)) * speed
				* delta;
		this.realPosY = realPosY + Math.sin(Math.toRadians(angle)) * speed
				* delta;
		posX = (int) realPosX;
		posY = (int) realPosY;
		recalcBorder = true;
		return true;
	}

	@Override
	public void hitItem(Item item) {
		if (item == owner && deadlyForOwner == false)
			return;

		if (item instanceof Tank || item instanceof Bullet) {
			aboutToExplode = true;
		}

		if (item instanceof Wall) {
			hit();
			if (!isAboutToExplode())
				this.angle = getBouncedAngle((Wall) item);
		}
	}

	public double getBouncedAngle(Wall wall) {

		// TODO Does not work always !!! Sometimes it flies through the wall
		int wx = wall.getX(), wy = wall.getY(), wsx = wall.getSizeX(), wsy = wall
				.getSizeY();

		int wxleft = (wx - wsx / 2), wxright = (wx + wsx / 2), wytop = (wy - wsy / 2), wybottom = (wy + wsy / 2);

		angle = (angle + 360) % 360; // normalize angle
		if (posX >= wxleft && posX <= wxright) {
			if ((angle < 180 && angle > 0) /* && wytop - posY > 0 */
					&& Math.abs(wytop - posY) <= speed) {
				// hitting at the top
				angle = (360 - angle) % 360;
			}
			if ((angle < 360 && angle > 180) /* && posY - wybottom > 0 */
					&& Math.abs(posY - wybottom) <= speed) {
				// hitting at the bottom
				angle = (360 - angle) % 360;
			}
		}
		if (posY >= wytop && posY <= wybottom) {
			if ((angle < 90 || angle > 270)
					&& /* wxleft - posX > 0 && */Math.abs(wxleft - posX) <= speed) {
				// hitting at the left
				angle = (180 - angle) % 360;
			}
			if ((angle < 270 && angle > 90)
					&& /* posX - wxright > 0 && */Math.abs(posX - wxright) <= speed) {
				// hitting at the right
				angle = (540 - angle) % 360;
			}
		}

		return angle;
	}

	public void explode(double delta) {
		if (explodeStart == 0) {
			if (this instanceof Mine) {
				owner.mineDestroyed();
			} else {
				if (this instanceof Bullet)
					owner.bulletDestroyed();
			}
		}
		super.explode(delta);
	}

	public Tank getOwner() {
		return owner;
	}

	@Override
	public Polygon getBorder() {
		if (recalcBorder) {
			border.reset();
			border.xpoints[0] = posX - (sizeX / 2);
			border.xpoints[1] = posX - (sizeX / 2);
			border.xpoints[2] = posX - (sizeX / 4);
			border.xpoints[3] = posX + (sizeX / 4);
			border.xpoints[4] = posX + (sizeX / 2);
			border.xpoints[5] = posX + (sizeX / 2);
			border.xpoints[6] = posX + (sizeX / 4);
			border.xpoints[7] = posX - (sizeX / 4);
			
			border.ypoints[0] = posY - (sizeY / 4);
			border.ypoints[1] = posY + (sizeY / 4);
			
			border.ypoints[2] = posY + (sizeY / 2);
			border.ypoints[3] = posY + (sizeY / 2);
			
			border.ypoints[4] = posY + (sizeY / 4);
			border.ypoints[5] = posY - (sizeY / 4);
			
			border.ypoints[6] = posY - (sizeY / 2);
			border.ypoints[7] = posY - (sizeY / 2);
			
			
			border.npoints = 8;
			recalcBorder = false;
		}
		return border;
	}

}
